<script setup lang="ts">
import {ref, watch} from 'vue'
import QuestionBasicInfo from './components/QuestionBasicInfo.vue'
import QuestionSettings from './components/QuestionSettings.vue'
import JudgeInfo from './components/JudgeInfo.vue'
import QuestionTypeSelector from './components/QuestionTypeSelector.vue'
import {QuestionType} from './types/questionTypes'
import {AddQuestionDTO, QuestionControllerService} from "../../../../generated";
import {ElMessage} from "element-plus";
import GenerateProgress from "../../../components/GenerateProgress.vue";
import {GenerateTypes} from "@/views/question/addQuestion/types/generatetTypes.ts";

// 创建表单对象
const form = ref<AddQuestionDTO>({
  title: '',
  content: '',
  type: QuestionType.PROGRAMMING,
  difficulty: 0,
  language: [] as string[],
  testCaseList: [{
    input: '',
    output: '',
    hint: '',
    score: 0
  }],
  analysis: '',
  timeLimit: 400,
  memoryLimit: 65535,
  tagList: [] as string[],
  choiceOptionList: [],
  isCorrect: 0,
  answer: [],
  referenceAnswer: '',
  score: 0
})

// 添加当前题目类型属性
const currentQuestionType = ref(QuestionType.PROGRAMMING)

watch(() => form.value.type, (newType) => {
  if (newType !== undefined) {
    currentQuestionType.value = newType;
  }
})

const isEditorFullscreen = ref(false)
const questionBasicInfoRef = ref()
const questionSettingsRef = ref()
const testCasesRef = ref()

const checkAvailable = () => {
  // 检查必填项
  if (!form.value.title) {
    ElMessage.error("标题不能为空");
    return false;
  }
  if (form.value.type === undefined) {
    ElMessage.error("请选择题目类型");
    return false;
  }
  if (form.value.difficulty === undefined) {
    ElMessage.error("请选择难度");
    return false;
  }

  // 检查分数
  if (form.value.type !== QuestionType.PROGRAMMING) {
    if (!form.value.score || form.value.score <= 0) {
      ElMessage.error("分数需大于零");
      return false;
    }
  }

  // 编程题特殊检查
  if (form.value.type === QuestionType.PROGRAMMING) {
    if (!form.value.language || form.value.language.length === 0) {
      ElMessage.error("至少需要支持一种编程语言");
      return false;
    }
    if (form.value.testCaseList && form.value.testCaseList.length > 0) {
      for (const testCase of form.value.testCaseList) {
        if (!testCase.score || testCase.score <= 0) {
          ElMessage.error("测试用例的分数需大于零");
          return false;
        }
      }
    }
  }

  // 选择题特殊检查
  if (form.value.type === QuestionType.MULTIPLE_CHOICE) {
    if (!form.value.choiceOptionList || form.value.choiceOptionList.length === 0) {
      ElMessage.error("选择题至少需要一个选项");
      return false;
    }
    const hasCorrectAnswer = form.value.choiceOptionList.some(option => option.isCorrect);
    if (!hasCorrectAnswer) {
      ElMessage.error("选择题至少需要一个正确答案");
      return false;
    }
  }

  return true;
}

const handleSubmit = async () => {
  // 根据题目类型，从JudgeInfo组件获取相应数据
  if (testCasesRef.value) {
    const answerData = testCasesRef.value.getAnswerData();
    form.value.score = answerData.score;
    // 根据题目类型合并数据
    switch (form.value.type) {
      case QuestionType.PROGRAMMING:
        // 编程题保持不变，使用testCase
        break;
      case QuestionType.MULTIPLE_CHOICE:
        // 选择题填入options数组
        form.value.choiceOptionList = answerData.options;
        break;
      case QuestionType.JUDGEMENT:
        // 判断题填入isCorrect
        form.value.isCorrect = answerData.isCorrect;
        form.value.analysis = answerData.analysis;
        break;
      case QuestionType.FILL_BLANK:
        // 填空题填入answer数组
        form.value.answer = answerData.answers;
        form.value.analysis = answerData.analysis;
        break;
      case QuestionType.COMPREHENSIVE:
        // 综合题填入referenceAnswer
        form.value.referenceAnswer = answerData.referenceAnswer;
        break;
    }
  }
  let check = checkAvailable();
  if (!check) {
    return;
  }
  // 提交表单
  let res = await QuestionControllerService.addQuestionUsingPost(form.value);
  if (res.code === 0) {
    ElMessage.success("添加成功")
    form.value = {
      title: '',
      content: '',
      type: QuestionType.PROGRAMMING,
      difficulty: 0,
      language: [] as string[],
      testCaseList: [{
        input: '',
        output: '',
        hint: '',
        score: 0
      }],
      timeLimit: 400,
      memoryLimit: 65535,
      tagList: [] as string[],
      choiceOptionList: [],
      isCorrect: 0,
      answer: [],
      referenceAnswer: '',
    }
  } else {
    ElMessage.error(res.message)
  }
}

const generateContent = async () => {
  try {
    let res = await QuestionControllerService.generateUsingPost({
      title: form.value.title,
      type: GenerateTypes.CONTENT
    });
    if (res.code === 0) {
      form.value.content = res.data.content
    } else {
      ElMessage.error(res.message)
    }

    // 调用组件方法重置生成状态
    if (questionBasicInfoRef.value) {
      questionBasicInfoRef.value.resetGenerating();
    }
  } catch (error) {
    ElMessage.error("生成内容失败");
    if (questionBasicInfoRef.value) {
      questionBasicInfoRef.value.resetGenerating();
    }
  }
}

const generateTags = async () => {
  try {
    // 调用标签生成接口
    let res = await QuestionControllerService.generateUsingPost({
      title: form.value.title,
      content: form.value.content,
      type: GenerateTypes.TAGS
    });

    if (res.code === 0) {
      form.value.tagList = res.data.tagList
    } else {
      ElMessage.error(res.message)
    }

    // 完成后重置加载状态
    if (questionSettingsRef.value) {
      questionSettingsRef.value.resetGeneratingTags();
    }
  } catch (error) {
    ElMessage.error("生成标签失败");
    if (questionSettingsRef.value) {
      questionSettingsRef.value.resetGeneratingTags();
    }
  }
}

const generateTestCase = async () => {
  try {
    console.log(testCasesRef.value);
    // 调用测试用例生成接口
    let res = await QuestionControllerService.generateUsingPost({
      title: form.value.title,
      content: form.value.content,
      type: GenerateTypes.TEST_CASE
    })
    console.log(testCasesRef.value);
    if (res.code === 0) {
      form.value.testCaseList = res.data.testCaseList
    } else {
      ElMessage.error(res.message)
    }
  } catch (error) {
    ElMessage.error("生成测试用例失败");
  } finally {
    // 确保无论成功还是失败都会重置状态
    if (testCasesRef.value) {
      testCasesRef.value.resetGeneratingTestCase();
    }
  }
}

const dialogVisible = ref(false)
const difficulties = [
  {label: '简单', value: 0},
  {label: '中等', value: 1},
  {label: '困难', value: 2}
]
const questionTypes = [
  {label: '编程题', value: QuestionType.PROGRAMMING},
  {label: '选择题', value: QuestionType.MULTIPLE_CHOICE},
  {label: '判断题', value: QuestionType.JUDGEMENT},
  {label: '填空题', value: QuestionType.FILL_BLANK},
  {label: '综合题', value: QuestionType.COMPREHENSIVE}
]
const questionType = ref(QuestionType.PROGRAMMING);
const difficulty = ref(0)
const selectedTags = ref<string[]>([])
const additionalContent = ref('')
const allTags = ref([
  '数组', '字符串', '排序', '哈希表', '动态规划', '贪心', '深度优先搜索',
  '广度优先搜索', '二分查找', '回溯', '栈', '队列', '链表', '树', '图'
])

const handleFullGenerate = () => {
  dialogVisible.value = true;
}

const isFullGenerating = ref(false)

const handleGenerateConfirm = async () => {
  dialogVisible.value = false;
  isFullGenerating.value = true;
  try {
    // 这里可以调用生成接口
    let res = await QuestionControllerService.generateUsingPost({
      difficulty: difficulty.value,
      tagList: selectedTags.value,
      additional: additionalContent.value,
      type: GenerateTypes.FULL,
      questionType: questionType.value
    });

    if (res.code === 0 && res.data) {
      form.value.title = res.data.title || '';
      form.value.content = res.data.content || '';
      form.value.difficulty = difficulty.value;
      form.value.tagList = res.data.tagList || [];

      // 根据题目类型处理不同的数据
      switch (questionType.value) {
        case QuestionType.PROGRAMMING:
          // 编程题保持不变，使用testCase
          if (res.data.testCaseList && res.data.testCaseList.length > 0) {
            form.value.testCaseList = res.data.testCaseList;
          }
          break;
        case QuestionType.MULTIPLE_CHOICE:
          // 选择题处理options
          if (res.data.choiceOptionList) {
            form.value.choiceOptionList = res.data.choiceOptionList;
          }
          break;
        case QuestionType.JUDGEMENT:
          // 判断题处理isCorrect和analysis
          if (res.data.isCorrect !== undefined) {
            form.value.isCorrect = res.data.isCorrect;
          }
          if (res.data.analysis) {
            form.value.analysis = res.data.analysis;
          }
          break;
        case QuestionType.FILL_BLANK:
          // 填空题处理answer和analysis
          if (res.data.answer) {
            form.value.answer = res.data.answer;
          }
          if (res.data.analysis) {
            form.value.analysis = res.data.analysis;
          }
          break;
        case QuestionType.COMPREHENSIVE:
          // 综合题处理referenceAnswer
          if (res.data.referenceAnswer) {
            form.value.referenceAnswer = res.data.referenceAnswer;
          }
          if (res.data.analysis) {
            form.value.analysis = res.data.analysis;
          }
          break;
      }

      // 设置题目类型
      form.value.type = questionType.value;

      ElMessage.success("题目生成成功");
    } else {
      ElMessage.error(res.message || "生成失败");
    }
  } catch (error) {
    ElMessage.error("生成题目失败");
  }
  difficulty.value = 0;
  selectedTags.value = [];
  additionalContent.value = '';
  isFullGenerating.value = false;
}
</script>

<template>
  <div class="update-question-container" :class="{ 'editor-fullscreen': isEditorFullscreen }">
    <GenerateProgress
        :visible="isFullGenerating"
        title="AI正在生成题目"
        :fullscreen="true"
    />
    <div class="page-header">
      <h2>添加题目</h2>
      <div>
        <el-button color="#626aef" @click="handleFullGenerate">AI 生成</el-button>
        <el-button type="primary" @click="handleSubmit">发布题目</el-button>
      </div>
    </div>

    <el-dialog
        v-model="dialogVisible"
        title="AI 生成题目"
        width="50%"
    >
      <el-form label-position="top">
        <el-form-item>
          <template #label>
            题目类型<span class="required-asterisk">*</span>
          </template>
          <el-select
              v-model="questionType"
              placeholder="请选择难度"
              class="full-width"
          >
            <el-option
                v-for="item in questionTypes"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <template #label>
            难度<span class="required-asterisk">*</span>
          </template>
          <el-select
              v-model="difficulty"
              placeholder="请选择难度"
              class="full-width"
          >
            <el-option
                v-for="item in difficulties"
                :key="item.value"
                :label="item.label"
                :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="标签">
          <el-select
              v-model="selectedTags"
              multiple
              filterable
              allow-create
              default-first-option
              placeholder="请选择标签"
              class="full-width"
          >
            <el-option
                v-for="tag in allTags"
                :key="tag"
                :label="tag"
                :value="tag"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="额外描述（可选）">
          <el-input
              v-model="additionalContent"
              type="textarea"
              :rows="4"
              placeholder="请输入您希望题目包含的额外内容描述"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleGenerateConfirm">
            开始生成
          </el-button>
        </div>
      </template>
    </el-dialog>

    <el-form
        ref="formRef"
        :model="form"
        label-position="top"
        class="question-form"
    >
      <QuestionBasicInfo
          ref="questionBasicInfoRef"
          v-model="form.title"
          v-model:content="form.content"
          v-model:question-type="form.type"
          :is-editor-fullscreen="isEditorFullscreen"
          @fullscreen-change="val => isEditorFullscreen = val"
          @generate-content="generateContent"
      />

      <QuestionTypeSelector
          v-model="form.type"
          :is-editor-fullscreen="isEditorFullscreen"
      />

      <QuestionSettings
          ref="questionSettingsRef"
          v-model:difficulty="form.difficulty"
          v-model:language="form.language"
          v-model:timeLimit="form.timeLimit"
          v-model:memoryLimit="form.memoryLimit"
          v-model:tags="form.tagList"
          :type="form.type"
          @generate:tags="generateTags"
      />

      <JudgeInfo
          ref="testCasesRef"
          v-model:testCase="form.testCaseList"
          :question-type="currentQuestionType"
          :options="form.choiceOptionList"
          :is-correct="form.isCorrect"
          :analysis="form.analysis"
          :answers="form.answer"
          :reference-answer="form.referenceAnswer"
          :score="0"
          @generate:testCase="generateTestCase"
      />
    </el-form>
  </div>
</template>

<style scoped>
.update-question-container {
  padding: 0 24px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--el-border-color-lighter);
}

.page-header h2 {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  position: relative;
  padding-left: 16px;
}

.page-header h2::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 20px;
  background-color: var(--el-color-primary);
  border-radius: 2px;
}

.question-form {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.required-asterisk {
  color: var(--el-color-danger);
  margin-left: 4px;
}

.full-width {
  width: 100%;
}
</style>
